본문으로 건너뛰기

Part 3: 사용자 개인정보 데이터흐름

항목내용
문서명Part 3: 사용자 개인정보 데이터흐름
제품명DTA Wide Sleep Management Platform
작성일2026-06-18
적용범위Part 3 (백엔드) — 사용자 개인·민감 데이터에 한정
관련 조항O.Purp_1/3/7, O.Data_1/2/3/5/6/7, O.Arch_2/5, O.TrdP_6/9/10, O.Ntwk_1
참조 표준BSI TR-03161, GDPR Art.30 (처리활동 기록)

1. 목적 및 범위

본 문서는 DTA Wide 백엔드(dta-wide-api)에서 처리되는 사용자 개인·민감 데이터의 수집·처리·저장·전송·삭제 흐름을 정의한다. 본 문서는 여러 BSI 조항의 공통 증빙 자료로 사용된다(§0 매핑 참조).

범위 한정: 본 문서는 개인·민감 데이터만 다룬다. 비개인 운영 데이터(설정, 룩업 테이블, 로그 인프라 등)와 앱 전반 아키텍처는 대상이 아니다. 시스템 아키텍처는 p3_01_backend_infra_architecture, 클라우드 위탁 책임은 p3_04_cloud_outsourcing_responsibility, 암호 키 수명주기는 p3_05_cryptographic_key_lifecycle를 참조한다.

본 문서의 모든 사실 단정은 코드·스키마 앵커(파일:라인)로 뒷받침된다.

0. 본 문서가 커버하는 BSI 조항

섹션커버 조항
§2 개인데이터 인벤토리·분류O.Purp_1 (BSIA-238), O.Data_3 (314), O.Arch_2 (246)
§3 데이터 흐름 다이어그램O.Arch_2 (246), O.Ntwk_1 (327)
§4 라이프사이클 (수집→삭제)O.Purp_3 (240), O.Data_2 (313), O.Data_7 (318)
§5 저장 맵 + at-rest 암호화O.Data_1 (312), O.Arch_4 (248)
§6 외부·서드파티 공유 매트릭스O.TrdP_6 (273), O.TrdP_9 (276), O.TrdP_10 (277), O.Purp_7 (244)
§7 인터페이스 보호·알림O.Arch_5 (249), O.Data_5 (316), O.Data_6 (317)

2. 개인데이터 인벤토리 및 분류

백엔드가 처리하는 개인·민감 데이터 카테고리. 저장 위치는 PostgreSQL(Cloud SQL, private 스키마)을 기본으로 한다.

카테고리데이터 항목저장 위치 (앵커)분류
신원 — eIDeidHash (SHA-256, unique)eid_links.eid_hash (private.prisma:247)가명화
신원 — eIDkvnr (보험번호, 영구 저장)eid_links.kvnr VarChar(10) (private.prisma:248)민감
신원 — eIDmetadata (sub·email·name [·insurer])eid_links.metadata Json (private.prisma:249)개인
신원 — eIDbirthdate미저장·미사용 (DTO에만 존재)
인증refresh/access token, app token, sessionRefreshToken/AccessToken/AppToken/Session (private.prisma:162/182/220/198)비밀
인증 — 2FA디바이스 공개키 (ECC P-256 SPKI)user_device_authentications.public_key_spki (private.prisma)공개키
동의동의/철회 이력, IP, 무결성 HMACuser_agreementments (private.prisma:307-329)개인
사용 이력userId, IP, User-Agent, 사용시각UsageHistory (private.prisma)개인
건강데이터수면 로그·설문 응답 (가공본)Firestore (agent-data 리포지토리)민감

eID 속성 저장 사실(정정 반영): eID 프로필 속성은 일시 폐기되지 않고 eid_links.metadata(Json)에 저장된다. 저장 필드는 쓰기 경로에 따라 다르다 — 신규 가입(eu-signup-orchestrator.service.ts:270-273)은 sub·email·name을, 링크 완료(complete-eid-link.handler.ts:104-110)는 여기에 insurer를 더해 저장한다. kvnr는 ePA 재인증 방지를 위해 영구 저장되며(스키마 주석, plan 177 agenda-001), 사용 시 마스킹된다(Kvnr.masked()kvnr.vo.ts:28). birthdate는 DTO에 존재하나 저장·사용되지 않는다(코호트는 access-code/OAuth state로 결정).


3. 데이터 흐름 다이어그램

개인데이터의 수집 → 저장 → (제한적) 외부 흐름을 신뢰경계와 함께 표시한다. 굵은 화살표(①)는 인입 수집, 점선(④)은 비활성(전송 없음) 경로다.

흐름 요약: ① 앱이 개인데이터를 TLS로 전송하면 API가 입력검증(ValidationPipe) 후, ② 카테고리별로 신뢰경계(GCP·EU) 내부에 저장한다(at-rest 암호화 — §5). 신뢰경계를 넘는 개인·민감 데이터 흐름은 ③ gematik과의 eID 본인확인 OAuth 핸드셰이크뿐이며 여기에 건강데이터·KVNR은 실리지 않는다. ④ KVNR의 유일한 외부 전송 경로(ePA)는 현재 stub이라 실 전송이 없다(§6 참조). 모든 인입 통신은 TLS로 암호화된다(O.Ntwk_1, p3_05/177-cryptography-justification).


4. 라이프사이클 (수집 → 처리 → 저장 → 전송 → 삭제)

단계처리 내용통제 / 앵커
수집인입 데이터는 전역 ValidationPipe(whitelist:true)로 검증, 미선언 필드 stripmain.ts:641-667 (O.Source_1 / BSIA-257)
처리목적 기반 최소화. KVNR 등 식별자는 마스킹 후 로깅kvnr.vo.ts:28, 로거 마스킹 (177-data-purpose-mapping)
저장카테고리별 저장소(§5). 민감 토큰·파일 URL은 필드 암호화auth.prisma:95, private.prisma:2082/2203
전송외부 전송은 §6 매트릭스에 한정. 건강데이터·KVNR의 외부 라이브 전송 없음§6
삭제계정 해지 시 eID 링크 삭제(eidLink.deleteMany), 2FA 디바이스 키는 Cascade 삭제private.prisma (UserDeviceAuthentication onDelete: Cascade)

보존·삭제 정책 상세는 177-data-retention-policy(O.Data_2/_7) 참조.


5. 저장 맵 및 at-rest 암호화

저장소저장 개인데이터at-rest 암호화
PostgreSQL (Cloud SQL)신원(eID)·인증·동의·사용 이력GCP 기본 저장 암호화(플랫폼) + 민감 필드 애플리케이션 암호화
Firestore가공 수면·설문 등 건강데이터GCP 기본 저장 암호화(플랫폼)
Redis (Memorystore)세션·캐시 (단기)GCP 기본 저장 암호화(플랫폼)

애플리케이션 레벨 필드 암호화(코드 확인):

  • refresh_token_cipher — 외부 IdP refresh token 암호화 저장 (auth.prisma:95)
  • file_url_cipher — 파일 URL 암호화 (private.prisma:2203)
  • encryption_key_id — 키 식별자 컬럼 (private.prisma:2082, 위와 별개 모델)

플랫폼 저장 암호화 및 키 관리 상세는 p3_05_cryptographic_key_lifecycle, 177-cryptography-justification을 참조한다.


6. 외부·서드파티 공유 매트릭스

백엔드가 개인데이터를 외부로 전송하는 경로 전체. (O.TrdP_6/9/10, O.Purp_7)

수신 대상전송 데이터목적보호 수단비고
gematik eID IdPOAuth 인증 핸드셰이크eID 본인확인TLS + OAuth/PKCE건강데이터 미전송
ePA export(KVNR — 미전송)ePA 연동 (구현 중)현재 stub 어댑터만 바인딩 — 라이브 전송 없음 (epa-export-stub.adapter.ts:16-25, 바인딩 feature-health-data-export.module.ts:103-104)
GCP 서브프로세서§5의 저장 데이터호스팅·저장·메시징DPA + 리전 고정(EU)Cloud SQL/Firestore/Redis/Pub-Sub/BigQuery (p3_04)

O.TrdP_6 (민감데이터 미전송): 건강데이터는 GCP 서브프로세서(저장 목적, DPA 하)를 제외하고 제3자에 전송되지 않는다. KVNR의 유일한 외부 egress 경로는 ePA export이나, 2026-06-18 기준 ePA 연동은 구현 중이며 운영에 바인딩된 유일 구현체는 stub 어댑터(EpaExportStubAdapter)다. stub은 EpaExportPort.send 호출 시 실제 전송 없이 경고 로그만 남기고 { accepted: true, referenceId: 'stub' }를 반환하며, KVNR은 로그에 남기지 않는다(epa-export-stub.adapter.ts:16-25). 도메인 핸들러의 epaPort.send(...) 호출(epa-export.handler.ts:158)은 DI 바인딩(feature-health-data-export.module.ts:103-104)에 따라 이 stub으로 귀결되므로, 호출 코드만으로는 라이브 전송으로 오해될 수 있으나 실 전송은 없다. TIC/Konnektor 인프라 준비 후 라이브 어댑터 교체 예정. O.TrdP_9 (외부서비스 고지): GCP 서브프로세서 및 데이터 공유 내역은 클라우드 위탁 문서(p3_04) 및 개인정보처리방침에 고지된다(사용자 대면 고지 화면은 P.1-Mobile/landing 범위).


7. 인터페이스 보호 및 알림

  • 인터페이스 보호 (O.Arch_5 / O.TrdP_10): 외부 서비스와의 모든 인터페이스는 TLS 암호화 + 인증/인가(스코프) + 입력 검증을 적용한다. 인입 검증은 §4(수집), 통신 암호화는 O.Ntwk_1(p3_05/177-cryptography-justification)을 따른다.
  • 데이터 export 통제 (O.Data_5): KVNR·건강데이터의 원천 외 반출은 §6 매트릭스에 한정되며, 그 외 export 경로는 존재하지 않는다.
  • 알림 페이로드 (O.Data_6): 식별자(KVNR 등)는 사용 시 마스킹된다(Kvnr.masked()kvnr.vo.ts:28). 알림/푸시 페이로드의 민감정보 배제는 O.Data_6 통제 항목으로 별도 관리한다.

부록: 근거 코드 앵커

사실앵커
eID 속성 metadata 저장complete-eid-link.handler.ts:104-110
eID 링크 모델/KVNR 영구저장private.prisma:244-263
동의/철회 이력 + 무결성 HMACprivate.prisma:307-329
KVNR 마스킹kvnr.vo.ts:28
ePA egress = stub (실 전송 없음)epa-export-stub.adapter.ts:16-25 + 바인딩 feature-health-data-export.module.ts:103-104 (호출부 epa-export.handler.ts:158)
인입 검증 (ValidationPipe)main.ts:641-667
필드 암호화 — refresh tokenauth.prisma:95 (refresh_token_cipher)
필드 암호화 — 파일 URLprivate.prisma:2203 (file_url_cipher), 키 식별자 private.prisma:2082 (encryption_key_id, 별개 모델)